home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MISC.SWG / 0075_UUDecode!.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  6KB  |  232 lines

  1. {
  2. > Yeah ! Please post your UU(EN/DE)CODE here ! I am interested, as well !
  3.  
  4. and the decode as well.
  5. }
  6.  
  7. program uudecode;
  8.  
  9.   CONST defaultSuffix = '.uue';
  10.         offset = 32;
  11.  
  12.   TYPE string80 = string[80];
  13.  
  14.   VAR infile: text;
  15.       fi    : file of byte;
  16.       outfile: file of byte;
  17.       lineNum: integer;
  18.       line: string80;
  19.       size,remaining :real;
  20.  
  21.   procedure Abort(message: string80);
  22.  
  23.     begin {abort}
  24.       writeln;
  25.       if lineNum > 0 then write('Line ', lineNum, ': ');
  26.       writeln(message);
  27.       halt
  28.     end; {Abort}
  29.  
  30.   procedure NextLine(var s: string80);
  31.  
  32.     begin {NextLine}
  33.       LineNum := succ(LineNum);
  34.       {write('.');}
  35.       readln(infile, s);
  36.       remaining:=remaining-length(s)-2;  {-2 is for CR/LF}
  37.       write('bytes remaining: ',remaining:7:0,' (',
  38.             remaining/size*100.0:3:0,'%)',chr(13));
  39.     end; {NextLine}
  40.  
  41.   procedure Init;
  42.  
  43.     procedure GetInFile;
  44.  
  45.       VAR infilename: string80;
  46.  
  47.       begin {GetInFile}
  48.         if ParamCount = 0 then abort ('Usage: uudecode <filename>');
  49.         infilename := ParamStr(1);
  50.         if pos('.', infilename) = 0
  51.           then infilename := concat(infilename, defaultSuffix);
  52.         assign(infile, infilename);
  53.         {$i-}
  54.         reset(infile);
  55.         {$i+}
  56.         if IOresult > 0 then abort (concat('Can''t open ', infilename));
  57.         writeln ('Decoding ', infilename);
  58.         assign(fi,infilename); reset(fi);
  59.         size:=FileSize(fi); close(fi);
  60.         if size < 0 then size:=size+65536.0;
  61.         remaining:=size;
  62.       end; {GetInFile}
  63.  
  64.     procedure GetOutFile;
  65.  
  66.       var header, mode, outfilename: string80;
  67.           ch: char;
  68.  
  69.       procedure ParseHeader;
  70.  
  71.         VAR index: integer;
  72.  
  73.         Procedure NextWord(var word:string80; var index: integer);
  74.  
  75.           begin {nextword}
  76.             word := '';
  77.             while header[index] = ' ' do
  78.               begin
  79.                 index := succ(index);
  80.                 if index > length(header) then abort ('Incomplete header')
  81.               end;
  82.             while header[index] <> ' ' do
  83.               begin
  84.                 word := concat(word, header[index]);
  85.                 index := succ(index)
  86.               end
  87.           end; {NextWord}
  88.  
  89.         begin {ParseHeader}
  90.           header := concat(header, ' ');
  91.           index := 7;
  92.           NextWord(mode, index);
  93.           NextWord(outfilename, index)
  94.         end; {ParseHeader}
  95.  
  96.       begin {GetOutFile}
  97.         if eof(infile) then abort('Nothing to decode.');
  98.         NextLine (header);
  99.         while not ((copy(header, 1, 6) = 'begin ') or eof(infile)) do
  100.           NextLine(header);
  101.         writeln;
  102.         if eof(infile) then abort('Nothing to decode.');
  103.         ParseHeader;
  104.         assign(outfile, outfilename);
  105.         writeln ('Destination is ', outfilename);
  106.         {$i-}
  107.         reset(outfile);
  108.         {$i+}
  109.         if IOresult = 0 then
  110.           begin
  111.            { write ('Overwrite current ', outfilename, '? [Y/N] ');
  112.             repeat
  113.               read (kbd, ch);
  114.               ch := UpCase(ch)
  115.             until ch in ['Y', 'N'];
  116.             writeln(ch);
  117.             if ch = 'N' then abort ('Overwrite cancelled.')}
  118.           end;
  119.         rewrite (outfile);
  120.       end; {GetOutFile}
  121.  
  122.     begin {init}
  123.       lineNum := 0;
  124.       GetInFile;
  125.       GetOutFile;
  126.     end; { init}
  127.  
  128.   Function CheckLine: boolean;
  129.  
  130.     begin {CheckLine}
  131.       if line = '' then abort ('Blank line in file');
  132.       CheckLine := not (line[1] in [' ', '`'])
  133.     end; {CheckLine}
  134.  
  135.  
  136.   procedure DecodeLine;
  137.  
  138.     VAR lineIndex, byteNum, count, i: integer;
  139.         chars: array [0..3] of byte;
  140.         hunk: array [0..2] of byte;
  141.  
  142. {    procedure debug;
  143.  
  144.       var i: integer;
  145.  
  146.       procedure writebin(x: byte);
  147.  
  148.         var i: integer;
  149.  
  150.         begin
  151.           for i := 1 to 8 do
  152.             begin
  153.               write ((x and $80) shr 7);
  154.               x := x shl 1
  155.             end;
  156.           write (' ')
  157.         end;
  158.  
  159.       begin
  160.         writeln;
  161.         for i := 0 to 3 do writebin(chars[i]);
  162.         writeln;
  163.         for i := 0 to 2 do writebin(hunk[i]);
  164.         writeln
  165.       end;      }
  166.  
  167.     function nextch: char;
  168.  
  169.       begin {nextch}
  170.         lineIndex := succ(lineIndex);
  171.         if lineIndex > length(line) then abort('Line too short.');
  172.         if not (line[lineindex] in [' '..'`'])
  173.           then abort('Illegal character in line.');
  174. {        write(line[lineindex]:2);}
  175.         if line[lineindex] = '`' then nextch := ' '
  176.                                  else nextch := line[lineIndex]
  177.       end; {nextch}
  178.  
  179.     procedure DecodeByte;
  180.  
  181.       procedure GetNextHunk;
  182.  
  183.         VAR i: integer;
  184.  
  185.         begin {GetNextHunk}
  186.           for i := 0 to 3 do chars[i] := ord(nextch) - offset;
  187.           hunk[0] := (chars[0] shl 2) + (chars[1] shr 4);
  188.           hunk[1] := (chars[1] shl 4) + (chars[2] shr 2);
  189.           hunk[2] := (chars[2] shl 6) + chars[3];
  190.           byteNum := 0  {;
  191.           debug          }
  192.         end; {GetNextHunk}
  193.  
  194.       begin {DecodeByte}
  195.         if byteNum = 3 then GetNextHunk;
  196.         write (outfile, hunk[byteNum]);
  197.         {writeln(bytenum, ' ', hunk[byteNum]);}
  198.         byteNum := succ(byteNum)
  199.       end; {DecodeByte}
  200.  
  201.     begin {DecodeLine}
  202.       lineIndex := 0;
  203.       byteNum := 3;
  204.       count := (ord(nextch) - offset);
  205.       for i := 1 to count do DecodeByte
  206.     end; {DecodeLine}
  207.  
  208.   procedure terminate;
  209.  
  210.     var trailer: string80;
  211.  
  212.     begin {terminate}
  213.       if eof(infile) then abort ('Abnormal end.');
  214.       NextLine (trailer);
  215.       if length (trailer) < 3 then abort ('Abnormal end.');
  216.       if copy (trailer, 1, 3) <> 'end' then abort ('Abnormal end.');
  217.       close (infile);
  218.       close (outfile)
  219.     end;
  220.  
  221.   begin {uudecode}
  222.     init;
  223.     NextLine(line);
  224.     while CheckLine do
  225.       begin
  226.         DecodeLine;
  227.         NextLine(line)
  228.       end;
  229.     terminate
  230.   end.
  231.  
  232.